実践! CDK for Terraform #1 導入
こんにちは!AWS 事業本部コンサルティング部のたかくに(@takakuni_)です。
皆さん、CDK for Terraform 使ってますでしょうか?私はあまり使っていません。
本エントリは、何本出るかわかりませんが、シリーズもので「CDK for Terraform 触っていこう」をモチベーションにしたブログになります。
田中 の執筆した「実践!AWS CDK」シリーズをパクらせて参考にさせていただき、 CDK for Terraform を入門できればと思います。
今回は「導入編」として、 CDK for Terraform のインストールと、軽くリソースをプロビジョニングしていきたいと思います。
CDK for Terraform とは
ざっくり解説すると以下になります。
- Cloud Development Kit for Terraform (略称 CDKTF または CDK for Terraform)
- TypeScript などのプログラミング言語を使ってインフラのプロビジョニングを行うフレームワーク
- Terraform で利用する HashiCorp Configuration Language の学習コストを減らせる
- アプリケーションコードから Terraform ファイルを生成してデプロイする
- テストコードが記述できる
CDK for Terraform を利用することで、Terraform の得意な部分であるマルチプラットフォームのプロビジョニングが、プログラミングコードで可能になります。
CDK for Terraform より画像引用
CDK for Terraform のインストール
今回は、 TypeScript で CDK for Terraform を利用します。
CKD for Terraform をインストールするには事前に以下が必要です。
- Terraform CLI(v1.2 以降)
- Node.js(v16 以降)
インストールは、 npm か、 Mac の場合は Homebrew を利用できます。
npm
npm install --global cdktf-cli@latest
Homebrew
brew install cdktf
インストールが完了すると、cdktf --version
でバージョンを確認してみましょう。
takakuni@~ % cdktf --version
0.17.1
プロジェクトの作成
まずは、空のディレクトリを作成し移動します。
mkdir cdktf-devio && cd cdktf-devio
続いて、ディレクトリ内で CDK for Terraform の初期化を行います。
cdktf init --template=typescript --local
すると、対話形式でプロジェクト名等の追加情報が質問されるため、回答します。
(今回は全部 Enter でスキップしました)
? Project Name cdktf-devio
? Project Description A simple getting started project for cdktf.
? Do you want to start from an existing Terraform project? no
? Do you want to send crash reports to the CDKTF team? Refer to https://developer.hashicorp.com/terraform/cdktf/create-and-deploy/configuration-file#enable-crash-reporting-for-the-cli for more information yes
Note: You can always add providers using 'cdktf provider add' later on
? What providers do you want to use?
初期化が完了すると、以下のフォルダ階層でプロジェクトが作成されます。
takakuni@cdktf-devio % tree . -L 1
.
├── __tests__
├── cdktf.json
├── help
├── jest.config.js
├── main.ts
├── node_modules
├── package-lock.json
├── package.json
├── setup.js
└── tsconfig.json
3 directories, 8 files
今後は、デプロイしたいリソースを main.ts
の MyStack クラスに定義していく流れになります。
import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
class MyStack extends TerraformStack {
constructor(scope: Construct, id: string) {
super(scope, id);
// define resources here
}
}
const app = new App();
new MyStack(app, "cdktf-devio");
app.synth();
リソースを定義してみる
プロバイダーの設定
Terraform には、 プロバイダーと呼ばれるプラットフォームごとに API をまとめたリストを提供しています。
AWS なら aws プロバイダー、 Google Cloud なら ```hclogle(https://registry.terraform.io/providers/hashicorp/google/latest) と言ったイメージです。
aws プロバイダーのプロビジョニング先リージョンを設定しようと思います。
まずはプロバイダーのインストールを行います。
npm install @cdktf/provider-aws
main.ts
を編集します。次のように、追記します。
import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
import { AwsProvider } from "@cdktf/provider-aws/lib/provider";
class MyStack extends TerraformStack {
constructor(scope: Construct, id: string) {
super(scope, id);
// define resources here
new AwsProvider(this, "aws", {
region: "ap-northeast-1",
});
}
}
const app = new App();
new MyStack(app, "cdktf-devio");
app.synth();
VPC の作成
aws_vpc を利用して、 VPC を作成していきましょう。
引き続き main.ts
を次のように編集します。
import { Construct } from "constructs";
import { App, TerraformStack } from "cdktf";
import { AwsProvider } from "@cdktf/provider-aws/lib/provider";
import { Vpc } from "@cdktf/provider-aws/lib/vpc";
class MyStack extends TerraformStack {
constructor(scope: Construct, id: string) {
super(scope, id);
// define resources here
new AwsProvider(this, "aws", {
region: "ap-northeast-1",
});
// VPC
new Vpc(this, 'vpc', {
cidrBlock: '10.0.0.0/16',
enableDnsHostnames: true,
enableDnsSupport: true,
tags: {
Name: 'cdktf-devio-vpc',
}
});
}
}
const app = new App();
new MyStack(app, "cdktf-devio");
app.synth();
Terraform ファイルの生成
cdktf synth
(synthesize)コマンドを使用して、コードから Terraform ファイルを生成します。
takakuni@cdktf-devio % cdktf synth
Generated Terraform code for the stacks: cdktf-devio
デフォルトで作成された Terraform ファイルは cdktf.out/stacks
配下に出力されてました。
{
"//": {
"metadata": {
"backend": "local",
"stackName": "cdktf-devio",
"version": "0.17.1"
},
"outputs": {
}
},
"provider": {
"aws": [
{
"region": "ap-northeast-1"
}
]
},
"resource": {
"aws_vpc": {
"vpc": {
"//": {
"metadata": {
"path": "cdktf-devio/vpc",
"uniqueId": "vpc"
}
},
"cidr_block": "10.0.0.0/16",
"enable_dns_hostnames": true,
"enable_dns_support": true,
"tags": {
"Name": "cdktf-devio-vpc"
}
}
}
},
"terraform": {
"backend": {
"local": {
"path": "/Users/takakuni/Desktop/cdktf-devio/terraform.cdktf-devio.tfstate"
}
},
"required_providers": {
"aws": {
"source": "aws",
"version": "5.6.2"
}
}
}
}
デプロイ
cdktf deploy
コマンドでアプリケーションコードを Terraform ファイルにコンパイルし、VPC をプロビジョニングします。
前回からの差分が表示し、差分に問題なければ Approve
を選択します。
takakuni@cdktf-devio % cdktf deploy
cdktf-devio Initializing the backend...
cdktf-devio Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
cdktf-devio - Using previously-installed hashicorp/aws v5.6.2
cdktf-devio Terraform has been successfully initialized!
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
cdktf-devio Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
cdktf-devio # aws_vpc.vpc (vpc) will be created
+ resource "aws_vpc" "vpc" {
+ arn = (known after apply)
+ cidr_block = "10.0.0.0/16"
+ default_network_acl_id = (known after apply)
+ default_route_table_id = (known after apply)
+ default_security_group_id = (known after apply)
+ dhcp_options_id = (known after apply)
+ enable_dns_hostnames = true
+ enable_dns_support = true
+ enable_network_address_usage_metrics = (known after apply)
+ id = (known after apply)
+ instance_tenancy = "default"
+ ipv6_association_id = (known after apply)
cdktf-devio + ipv6_cidr_block = (known after apply)
+ ipv6_cidr_block_network_border_group = (known after apply)
+ main_route_table_id = (known after apply)
+ owner_id = (known after apply)
+ tags = {
+ "Name" = "cdktf-devio-vpc"
}
+ tags_all = {
+ "Name" = "cdktf-devio-vpc"
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
cdktf-devio Enter a value: yes
cdktf-devio aws_vpc.vpc (vpc): Creating...
cdktf-devio aws_vpc.vpc (vpc): Still creating... [10s elapsed]
cdktf-devio aws_vpc.vpc (vpc): Creation complete after 12s [id=vpc-08667013746e9fb49]
cdktf-devio
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
No outputs found.
手動で変更してみる
試しに、手動で変更してみます。
再度 cdktf deploy
をしてみると差分が表示され、元に戻すことができました。
takakuni@cdktf-devio % cdktf deploy
cdktf-devio Initializing the backend...
cdktf-devio Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
cdktf-devio - Using previously-installed hashicorp/aws v5.6.2
Terraform has been successfully initialized!
cdktf-devio
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
cdktf-devio aws_vpc.vpc (vpc): Refreshing state... [id=vpc-08667013746e9fb49]
cdktf-devio Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
~ update in-place
Terraform will perform the following actions:
cdktf-devio # aws_vpc.vpc (vpc) will be updated in-place
~ resource "aws_vpc" "vpc" {
~ enable_dns_hostnames = false -> true
~ enable_dns_support = false -> true
id = "vpc-08667013746e9fb49"
tags = {
"Name" = "cdktf-devio-vpc"
}
# (13 unchanged attributes hidden)
}
Plan: 0 to add, 1 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
cdktf-devio Enter a value: yes
cdktf-devio aws_vpc.vpc (vpc): Modifying... [id=vpc-08667013746e9fb49]
cdktf-devio aws_vpc.vpc (vpc): Still modifying... [id=vpc-08667013746e9fb49, 10s elapsed]
cdktf-devio aws_vpc.vpc (vpc): Still modifying... [id=vpc-08667013746e9fb49, 20s elapsed]
cdktf-devio aws_vpc.vpc (vpc): Modifications complete after 22s [id=vpc-08667013746e9fb49]
cdktf-devio
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
No outputs found.
リソースの削除
cdktf destroy
コマンドでリソースを削除します。無事削除が完了したようです。
takakuni@cdktf-devio % cdktf destroy
cdktf-devio Initializing the backend...
cdktf-devio Initializing provider plugins...
- Reusing previous version of hashicorp/aws from the dependency lock file
cdktf-devio - Using previously-installed hashicorp/aws v5.6.2
Terraform has been successfully initialized!
cdktf-devio
You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
cdktf-devio aws_vpc.vpc (vpc): Refreshing state... [id=vpc-08667013746e9fb49]
cdktf-devio Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
- destroy
Terraform will perform the following actions:
cdktf-devio # aws_vpc.vpc (vpc) will be destroyed
- resource "aws_vpc" "vpc" {
- arn = "arn:aws:ec2:ap-northeast-1:123456789012:vpc/vpc-08667013746e9fb49" -> null
- assign_generated_ipv6_cidr_block = false -> null
- cidr_block = "10.0.0.0/16" -> null
- default_network_acl_id = "acl-0ab0232dc86c525ce" -> null
- default_route_table_id = "rtb-0b8a13b2c1a713934" -> null
- default_security_group_id = "sg-0ffd80b65fdcb12f9" -> null
- dhcp_options_id = "dopt-03c00cf53d618e49b" -> null
- enable_dns_hostnames = true -> null
cdktf-devio - enable_dns_support = true -> null
- enable_network_address_usage_metrics = false -> null
- id = "vpc-08667013746e9fb49" -> null
- instance_tenancy = "default" -> null
- ipv6_netmask_length = 0 -> null
- main_route_table_id = "rtb-0b8a13b2c1a713934" -> null
- owner_id = "622809842341" -> null
- tags = {
- "Name" = "cdktf-devio-vpc"
} -> null
- tags_all = {
- "Name" = "cdktf-devio-vpc"
} -> null
}
Plan: 0 to add, 0 to change, 1 to destroy.
Do you really want to destroy all resources?
cdktf-devio Terraform will destroy all your managed infrastructure, as shown above.
There is no undo. Only 'yes' will be accepted to confirm.
cdktf-devio Enter a value: yes
cdktf-devio aws_vpc.vpc (vpc): Destroying... [id=vpc-08667013746e9fb49]
cdktf-devio aws_vpc.vpc (vpc): Destruction complete after 1s
cdktf-devio
Destroy complete! Resources: 1 destroyed.
おわりに
以上、「実践! CDK for Terraform #1 導入」でした。このような流れで、 CDK for Terraform をゆっくり入門していきたいと思います。
AWS 事業本部コンサルティング部のたかくに(@takakuni_)でした!